<?php 
/**
 * Class responsavel em fazer paginacao
 * versao: 0.1.3
 * Desenvolvido : Cristian Cardoso
 */
class Paginacao
{

    private $paginaAtual;
    private $url;
    private $urlParametros;
    private $div;
    private $class;
    private $totalRagistros;
    private $totalRagistrosPorPagina;
    private $numeroDeBotoes;
    private $tabela;
    private $sql;
    private $quantidadeDePaginas;
    private $paginaCadaLado;
    private $paginacao;
    private $linkInicio;
    private $linkMeio;
    private $linkFim;
    private $criterios;

    /**
     * Inicia atributos
     */
    public function __construct()
    {
        $this->urlParametros = array ();
        $this->totalRagistrosPorPagina = 20;
        $this->numeroDeBotoes = 11;
    }

    /**
     * Define o numero da pagina que se encontra
     *
     * @param array $array 4 posições: campos do banco, comparador, valor, and ou or preferencial
     */
    public function setCriterios($array)
    {
        $this->criterios = $array;
    }

    /**
     * Metodo responsavel em retornar a pagina que se encontra
     *
     * @return array
     */
    public function getCriterios()
    {
        return $this->criterios;
    }
    /**
     * Define o numero da pagina que se encontra
     *
     * @param integer $numero Numero da pagina q se encontra
     */
    public function setPaginaAtual($numero)
    {
        $this->paginaAtual = intval($numero);
    }

    /**
     * Metodo responsavel em retornar a pagina que se encontra
     *
     * @return integer
     */
    public function getPaginaAutal()
    {
        return $this->paginaAtual;
    }

    /**
     * Define a url que devera redirecionar
     *
     * @param string $url url a ser redirecionada
     */
    public function setUrl($url)
    {
        $this->url = $url;
    }

    /**
     * Define parametros para ser passado junto pela url
     *
     * @param string $var nome da variavel
     * @param string $valor Valor da variavel
     */
    public function setUrlParametros($var, $valor)
    {
        $this->urlParametros[rawurlencode($var)] = rawurlencode($valor);
    }

    /**
     * Define o nome da div caso queira utilizar paginação com ajax (funcao LOAD)
     *
     * @param string $div div que ira receber o conteudo da pagina
     */
    public function setDiv($div)
    {
        $this->div = $div;
    }

    /**
     * Define qual a class a ser utilizada nos links
     * nao esta funcionando (nao foi implementado ate o momento)
     *
     * @param string $class = tesrt
     */
    public function setClass($class)
    {
        $this->class = $class;
    }

    /**
     * Define o numero total de registros a serem paginados
     *
     * @param integer $numero Quantidade de registros
     */
    public function setTotalRegistros($numero)
    {
        $this->totalRagistros = intval($numero);
    }

    /**
     * Retorna o numero total de registros;
     *
     * @return inteiro
     */
    public function getTotalRegistros()
    {
        return $this->totalRagistros;
    }

    /**
     * Define o numero de registros que devera aparecer por paginas
     *
     * @param integer $numero Quantidade de registros
     */
    public function setTotalRagistrosPorPagina($numero)
    {
        $this->totalRagistrosPorPagina = intval($numero);
    }

    /**
     * Define o numero maximo de botoes que ira aparecer na paginação
     *
     * @param integer $numero Quantidade de botoes
     */
    public function setNumeroDeBotoes($numero)
    {
        if ( ! (1 & $numero) )
        {
            $numero++;
        }
        $this->numeroDeBotoes = $numero;
    }

    /**
     * Define o nome da tabela a ser consultada,
     * ira executar o comando comforme exemplo
     *
     * @param string $tabela nome da tabela
     * @param string $pdo conexao com banco de dados
     * @example SELECT COUNT(*) AS numero_registros FROM $tabela
     */
    public function setTabela($tabela,$pdo = false)
    {
        $this->tabela = $tabela;
        
        if ($pdo) {
            $sql = "SELECT COUNT(*) AS numero_registros FROM {$this->tabela}";
            $sql .= $this->criterios();
            $linha = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
            $this->setTotalRegistros($linha['numero_registros']);
        } else {
            try {
                $pdo = Conexao::open('sistema');
                $sql = "SELECT COUNT(*) AS numero_registros FROM {$this->tabela}";
                $sql .= $this->criterios();
                $linha = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
                $this->setTotalRegistros($linha['numero_registros']);
                unset($pdo);
            } catch ( PDOException $e ) {
                new Excecao($e);
            }
        }
    }

    private function criterios() {
        $array = $this->criterios;
        $sql = null;
        if((is_array($array))&&(!empty($array))) {
            $sql = ' WHERE ';
            $i=0;
            foreach ($array as $value) {
                $i++;
                $sql .= "{$value[0]} {$value[1]} {$value[2]} ";
                if(count($array)>$i) {
                    $sql .= empty($value[3]) ? ' AND ' : ' '.strtoupper(trim($value[3])).' ';
                }
            }
        }
        return $sql;
    }

    /**
     * Define o sql a ser executado para retornar o numero de registros.
     *
     * @param string $sql instrução sql
     */
    public function setSql($sql, $pdo = false)
    {
        $this->sql = $sql;
        if ($pdo) {
            $consulta = $pdo->prepare($sql);
            $consulta->execute();
            $this->setTotalRegistros($consulta->rowCount());
        } else {
            try {
                $pdo = Conexao::open('sistema');
                $consulta = $pdo->prepare($sql);
                $consulta->execute(); 
                $this->setTotalRegistros($consulta->rowCount());
                unset($pdo);
            } catch ( PDOException $e ) {
                new Excecao($e);
            }
        }
    }

    /**
     * Responsavel em padronizar e montar o modelo dos links.
     */
    private function montaLink()
    {
        if ( empty($this->div) )
        {
            if ( empty($this->urlParametros) )
            {
                $this->linkInicio = "<a href=\"" . $this->url . "?pg=";
                $this->linkMeio = "\">";
            }
            else
            {
                $this->linkInicio = "<a href=\"" . $this->url . "?pg=";
                $this->linkMeio = "&" . http_build_query($this->urlParametros) . "\">";
            }
        }
        else
        {
            if ( empty($this->urlParametros) )
            {
                $this->linkInicio = "<a onclick=Load('" . $this->url . "?pg=";
                $this->linkMeio = "','" . $this->div . "');>";
            }
            else
            {
                $this->linkInicio = "<a onclick=Load('" . $this->url . "?pg=";
                $this->linkMeio = "&" . http_build_query($this->urlParametros) . "','" . $this->div . "');>";
            }
        }
        $this->linkFim = '</a>';
    }

    /**
     * Responsavel em montar a paginacao
     *
     * @return string Ira retornar a string da paginacao
     */
    public function getMontaPaginacao()
    {

        if ( $this->totalRagistros == 0 )
        {
            return "";
        }
        $this->montaLink();

        $this->quantidadeDePaginas = ceil($this->totalRagistros / $this->totalRagistrosPorPagina);

        if ( $this->quantidadeDePaginas != 0 )
        {
            $this->paginaAtual = ($this->paginaAtual < 1) ? 1 : $this->paginaAtual;
            $this->paginaAtual = ($this->paginaAtual > $this->quantidadeDePaginas) ? $this->quantidadeDePaginas : $this->paginaAtual;
        }

        $this->paginaCadaLado = (($this->numeroDeBotoes - 1) / 2);

        if ( $this->paginaAtual == 1 )
        {
            $this->paginacao .= '<font><b>Primeira</b></font>';
            $this->paginacao .= '&nbsp;|&nbsp;<font><b>Anterior</b></font>';
        }
        else
        {
            $this->paginacao .= $this->linkInicio . "1" . $this->linkMeio . "Primeira" . $this->linkFim;
            $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . ($this->paginaAtual - 1) . $this->linkMeio . "Anterior" . $this->linkFim;
        }

        if ( $this->quantidadeDePaginas <= $this->numeroDeBotoes )
        {
            for ( $i = 1; $i != $this->quantidadeDePaginas + 1; $i++ )
            {
                if ( $this->paginaAtual == $i )
                {
                    $this->paginacao .= '&nbsp;|&nbsp;<span><b>[&nbsp;' . $i . '&nbsp;]</b></span>';
                }
                else
                {
                    $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . $i . $this->linkMeio . $i . $this->linkFim;
                }
            }
        }
        else
        {
            $num_do_link_esq = $this->paginaAtual - $this->paginaCadaLado;
            $num_do_link_dir = $this->paginaAtual + $this->paginaCadaLado;

            while ( $num_do_link_esq < 1 )
            {
                $num_do_link_dir++;
                $num_do_link_esq++;
            }
            while ( $num_do_link_dir > $this->quantidadeDePaginas )
            {
                $num_do_link_dir--;
                $num_do_link_esq--;
            }

            for ( $i = $num_do_link_esq; $i < $this->paginaAtual; $i++ )
            {
                $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . $i . $this->linkMeio . $i . $this->linkFim;
            }

            $this->paginacao .= "&nbsp;|&nbsp;<font><b>[&nbsp;" . $this->paginaAtual . "&nbsp;]</b></font>";

            for ( $i = $this->paginaAtual + 1; $i != $num_do_link_dir + 1; $i++ )
            {
                $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . $i . $this->linkMeio . $i . $this->linkFim;
            }
        }

        if ( $this->paginaAtual < $this->quantidadeDePaginas )
        {
            $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . ($this->paginaAtual + 1) . $this->linkMeio . "Pr&oacute;xima" . $this->linkFim;
            $this->paginacao .= "&nbsp;|&nbsp;" . $this->linkInicio . ($this->quantidadeDePaginas) . $this->linkMeio . "Ultima" . $this->linkFim;
        }
        else
        {
            $this->paginacao .= "&nbsp;|&nbsp;<font><b>Pr&oacute;xima</b></font>";
            $this->paginacao .= "&nbsp;|&nbsp;<font><b>Ultima</b></font>";
        }
        return $this->paginacao;
    }

    /**
     * Ira retornar o numero que deve ser iniciado a consulta sql
     *
     * @return integer
     */
    public function getPesquisaInicial()
    {
        return ($this->paginaAtual - 1) * $this->totalRagistrosPorPagina;
    }
}
